home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / doom / ldhe-src.0 / ldhe-src / dehacked / source / print.cc < prev    next >
C/C++ Source or Header  |  1995-05-31  |  22KB  |  948 lines

  1. // DeHackEd version 2.3
  2. // Written by Greg Lewis, gregl@umich.edu
  3. // If you release any versions of this code, please include
  4. // the author in the credits.  Give credit where credit is due!
  5.  
  6. #include <sys/types.h>
  7. #include <ctype.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12. #include "dehacked.h"
  13. #include "print.h"
  14. #include "linux_text.h"
  15.  
  16. #undef TEXT
  17. #undef WIDTH
  18. #undef HEIGHT
  19. #include "ttyobj.h"
  20.  
  21. // Gets the frame name and puts it into string.
  22.  
  23. void Getframename(int framenum, char *string)
  24. {
  25.     char sprite[5];
  26.  
  27.     if (framenum == 0)
  28.         strcpy(string, "none");
  29.     else if (framenum > 0 && framenum <= numobj[FRAME][version]) {
  30.         if ( Lnx_DOOM ) {
  31.             Getspritename((int)framedata[framenum][SPRITENUM], sprite);
  32.             sprintf(string, "%s%c", sprite, (char)(framedata[framenum][SPRITESUB] + 'A'));
  33.         } else
  34.             sprintf(string, "%s%c", &(textdatap[spritedata[framedata[framenum][SPRITENUM]] - toff[version]]),
  35.                                         (char)(framedata[framenum][SPRITESUB] + 'A'));
  36.     } else
  37.         strcpy(string, "ERROR");
  38. }
  39.  
  40. // Gets the sound name and puts it into string.
  41.  
  42. void Getsoundname(int soundnum, char *string)
  43. {
  44.     soundnum--;
  45.  
  46. #ifdef DEBUG
  47. fprintf(stderr, "Looking up sound number %d..\n", soundnum);
  48. if ( soundnum >= 0 )
  49.     fprintf(stderr, "Offset = %ld\n", sounddata[soundnum][TEXTP]);
  50. #endif
  51.     if (soundnum == -1)
  52.         strcpy(string, "none");
  53.     else if (soundnum < 0 || soundnum > numobj[SOUND][version])
  54.         strcpy(string, "ERROR");
  55.     else if ( Lnx_DOOM )
  56.         strncpy(string, lnx_strings[SOUND_NAMES].text[numobj[SOUND][version]-soundnum-1], 6);
  57.     else if (sounddata[soundnum][TEXTP] < toff[version])
  58.         strcpy(string, "ERROR");
  59.     else if (sounddata[soundnum][TEXTP] > toff[version] + size[TXT][version])
  60.         strcpy(string, "ERROR");
  61.     else
  62.         strncpy(string, &(textdatap[(sounddata[soundnum][TEXTP]) - toff[version]]), 6);
  63.     string[6] = 0;
  64. }
  65.  
  66. // Gets the sprite name and puts it into a string
  67.  
  68. void Getspritename(int spritenum, char *string)
  69. {
  70.     if (spritenum < 0 || spritenum > numobj[SPRITE][version])
  71.         strcpy(string, "ERROR");
  72.     else if ( Lnx_DOOM )
  73.         strncpy(string, lnx_strings[SPRITE_NAMES].text[numobj[SPRITE][version]-spritenum-1], 4);
  74.     else if (spritedata[spritenum] < toff[version])
  75.         strcpy(string, "ERROR");
  76.     else if (spritedata[spritenum] > toff[version] + size[TXT][version])
  77.         strcpy(string, "ERROR");
  78.     else
  79.         strncpy(string, &(textdatap[spritedata[spritenum] - toff[version]]), 4);
  80.     string[4] = 0;
  81. }
  82.  
  83. // Gets the thing name from the array of names
  84.  
  85. void Getthingname(int thingnum, char *string)
  86. {
  87.     if (version == DOOM1_2)
  88.         strcpy(string, namelist[thingconvar[thingnum]]);
  89.     else
  90.         strcpy(string, namelist[thingnum]);
  91. }
  92.  
  93. // Gets a text number from a text offset
  94. // Needs to work with Linux.  FIXME!!
  95. int Gettextnum(int offset)
  96. {
  97.     int i = 0, stringlen, current = 0;
  98.  
  99.     offset -= (int)toff[version];
  100.  
  101.     while (current < offset)
  102.     {
  103.         stringlen = strlen(&(textdatap[current]));
  104.         current += (stringlen & (~3)) + 4;
  105.         i++;
  106.     }
  107.  
  108.     return i;
  109. }
  110.  
  111. // Turn strings certain colors if they are "none" or "ERROR".
  112.  
  113. void Highlightname(char *name)
  114. {
  115.     if (strcmp(name, "ERROR") == 0)
  116.         textattr(NERROR);
  117.     else if (strcmp(name, "none") == 0)
  118.         textattr(NGRAY);
  119.     else
  120.         textattr(NORMAL);
  121. }
  122.  
  123. // Prints the ammo screen
  124.  
  125. void Printammo(void)
  126. {
  127.     char order[5] = {BOB1FRAME, BOB2FRAME, BOB3FRAME, SHOOTFRAME, FIREFRAME};
  128.     char temp[10];
  129.     char na[9] = "N/A     ";
  130.     int curweapon = global[AMMO_EDIT][CUR];
  131.     int i;
  132.  
  133.     textattr(NORMAL);
  134.  
  135.     if (redraw == ALL)
  136.     {
  137.         Drawframe(0, NORMAL, 20, 18, 60, 32);
  138.         CPutsXY(arrows[AMMO_EDIT][0], arrows[AMMO_EDIT][1], up_arrows[IBM_CHARSET]);
  139.         CPutsXY(arrows[AMMO_EDIT][2], arrows[AMMO_EDIT][3], down_arrows[IBM_CHARSET]);
  140.     }
  141.  
  142.     CPutsXY(22, 20, "Weapon number");
  143.     CPutsXY(22, 21, "Weapon name");
  144.     CPutsXY(22, 22, "Ammo type");
  145.  
  146.  
  147.     for (i=0; i<11; i++)
  148.     {
  149.         textattr(NORMAL);
  150.         switch (redraw)
  151.         {
  152.             case ALL:
  153.                 if (i > 2)
  154.                     CPutsXY(22, i+20, fullwepfields[i-3]);
  155.                 if (i > 5)
  156.                 {
  157.                     CPutsXY(52, i+20, "[");
  158.                     CPutsXY(58, i+20, "]");
  159.                 }
  160.             case ALLDATA:
  161.             case DATA:
  162.                 gotoxy(39, i+20);
  163.                 switch (i)
  164.                 {
  165.                     case 0:
  166.                         cprintf("%-2d", curweapon+1);
  167.                         break;
  168.                     case 1:
  169.                         cprintf("%-16s", weaponlist[curweapon]);
  170.                         break;
  171.                     case 2:
  172.                         if (weapondata[curweapon][AMMOTYPE] > numobj[AMMO][version]+1)
  173.                             cputs(na);
  174.                         else
  175.                             cprintf("%-9s", ammolist[weapondata[curweapon][AMMOTYPE]]);
  176.                         break;
  177.                     case 3:
  178.                         cprintf("%-11ld", weapondata[curweapon][AMMOTYPE]);
  179.                         break;
  180.                     case 4:
  181.                         if (weapondata[curweapon][AMMOTYPE] >= numobj[AMMO][version])
  182.                             cputs(na);
  183.                         else
  184.                             cprintf("%-11ld", maxammodata[weapondata[curweapon][AMMOTYPE]]);
  185.                         break;
  186.                     case 5:
  187.                         if (weapondata[curweapon][AMMOTYPE] >= numobj[AMMO][version])
  188.                             cputs(na);
  189.                         else
  190.                             cprintf("%-11ld", perammodata[weapondata[curweapon][AMMOTYPE]]);
  191.                         break;
  192.                     case 6:
  193.                     case 7:
  194.                     case 8:
  195.                     case 9:
  196.                     case 10:
  197.                         cprintf("%-11ld", weapondata[curweapon][order[i-6]]);
  198.  
  199.                         Getframename((int)weapondata[curweapon][order[i-6]], temp);
  200.                         Highlightname(temp);
  201.                         CPrintfXY(53, i+20, "%-5s", temp);
  202.                 }
  203.             case NOT:    // Don't do any redraw.
  204.                 break;
  205.         }
  206.     }
  207. }
  208.  
  209. // Prints the frame screen
  210.  
  211. void Printframe(void)
  212. {
  213.     int i, j, current, start = 0, end = 38;
  214.     char buffer[6];
  215.     char xloc[6] = {22, 28, 35, 42, 52, 61};
  216.     char pformat[6][5] = {"%5ld", "%3ld", "", "%5ld", "%8ld", "%8ld"};
  217.     char order[6] = {SPRITENUM, SPRITESUB, SPRITESUB, NEXTFRAME, DURATION, ACTIONPTR};
  218.  
  219.     current = global[FRAME_EDIT][TOPROW];
  220.  
  221.     if (redraw == DATA)
  222.     {
  223.         if (current == global[FRAME_EDIT][CUR])
  224.             end = 2;
  225.         else if (current + 37 == global[FRAME_EDIT][CUR])
  226.         {
  227.             start = 35;
  228.             current += 35;
  229.         }
  230.         else
  231.         {
  232.             start = (global[FRAME_EDIT][CUR] - current) - 1;
  233.             end = (global[FRAME_EDIT][CUR] - current) + 2;
  234.             current = global[FRAME_EDIT][CUR] - 1;
  235.         }
  236.     }
  237.  
  238.     textattr(NORMAL);
  239.  
  240.     if (redraw == ALL)
  241.     {
  242.         Drawframe(0, NORMAL, 4, 3, 76, 47);
  243.                         // 567890123456789012345678901234567890123456789012345678901234567890
  244.         CPutsXY(7, 5, "Frame             Sprite   Bright   Next                  Code");
  245.         CPutsXY(7, 6, "Number   Name     # sub#   Sprite  Frame #   Duration   Pointer");
  246.         CPutsXY(arrows[FRAME_EDIT][0], arrows[FRAME_EDIT][1], up_arrows[IBM_CHARSET]);
  247.         CPutsXY(arrows[FRAME_EDIT][2], arrows[FRAME_EDIT][3], down_arrows[IBM_CHARSET]);
  248.     }
  249.  
  250.     for (i=start; i<end; current++, i++)
  251.     {
  252.         CPrintfXY(7, i+8, "%4d", current);
  253.  
  254.         Getframename(current, buffer);
  255.         Highlightname(buffer);
  256.         CPrintfXY(16, i+8, "%-5s", buffer);
  257.  
  258.         textattr(NORMAL);
  259.  
  260.         for (j=0; j<6; j++)
  261.         {
  262.             gotoxy(xloc[j], i+8);
  263.             if (j == 2)
  264.             {
  265.                 CPutsXY(35, i+8, "[ ]");
  266.                 gotoxy(36, i+8);
  267.                 if (framedata[current][SPRITESUB] & 32768L)
  268.                     putch('X');
  269.             }
  270.             else if (j == 1)
  271.                 cprintf(pformat[j], framedata[current][order[j]] & 255);
  272.             else
  273.                 cprintf(pformat[j], framedata[current][order[j]]);
  274.         }
  275.     }
  276. }
  277.  
  278. // Prints the help screen.
  279.  
  280. void Printhelp(void)
  281. {
  282.     char *keys[21] = {"Esc", "Enter", "Space", "a", "c", "g", "j",    "l", "o",
  283.                             "r", "s", "u", "w", "z", "F2", "F3", "F4", "F5", "F6",
  284.                             "F7", "F8"};
  285.     char *effects[21] = {"quit DeHackEd",
  286.                                 "edit the current field",
  287.                                 "view/play the current field",
  288.                                 "about DeHackEd",
  289.                                 "copy from one object to another",
  290.                                 "go to a specific object",
  291.                                 "jump to the current item in its editor",
  292.                                 "load a patch file into DeHackEd",
  293.                                 "save an old-format patch file",
  294.                                 "run Doom",
  295.                                 "save a patch file (new text format)",
  296.                                 "undo all changes--reload hacked Doom exe",
  297.                                 "write current changes to hacked Doom exe",
  298.                                 "zap all changes; reload original exe",
  299.                                 "Thing editor",
  300.                                 "Frame editor",
  301.                                 "Ammo/Weapon editor",
  302.                                 "Sound editor",
  303.                                 "Sprite editor",
  304.                                 "Text editor",
  305.                                 "Thing list"};
  306.     int i;
  307.     int *image;
  308.  
  309.     image = new int[2170];
  310.  
  311.     if (image == NULL)
  312.         AbortProg("in Help");
  313.  
  314.     gettext(10, 8, 71, 41, image);
  315.  
  316.     Drawframe(1, INFO, 10, 8, 70, 40);
  317.     textattr(INFO);
  318.  
  319.     CPutsXY(35, 10, "Help Screen");
  320.     CPutsXY(14, 12, "Refer to the DEHACKED.HLP file for general user help");
  321.     CPutsXY(12, 13, "and complete key information.  Use arrow keys or mouse");
  322.     CPutsXY(12, 14, "to move between fields.  The left mouse button selects,");
  323.     CPutsXY(12, 15, "and the right mouse button is Escape.");
  324.     CPutsXY(14, 16, "Here is a list of available keys:");
  325.  
  326.     for (i=0; i<21; i++)
  327.         CPrintfXY(18, i+18, "%-7s- %s", keys[i], effects[i]);
  328.  
  329.     Waitforevent(YES);
  330.  
  331.     puttext(10, 8, 71, 41, image);
  332.  
  333.     delete image;
  334. }
  335.  
  336. // Prints the intro window
  337.  
  338. void Printintro(void)
  339. {
  340.     int *image;
  341.     int *image2;
  342.     char *about[14] = {"DeHackEd 2.3",
  343.                           "The premiere Doom exe Hack Editor",
  344.                           "",
  345.                           "Written by Greg Lewis (Tree)",
  346.                           "Email: gregl@umich.edu",
  347.                           "",
  348.                           "Ported to Linux by Sam Lantinga",
  349.                           "Email: slouken@cs.ucdavis.edu",
  350.                           "",
  351.                           "Special thanks to:",
  352.                           "The cool guys of iD, for Doom",
  353.                           "Matt Fell, for the Doom.exe specs",
  354.                           "The many others who have helped",
  355.                           "in the creation of this program!"};
  356.     int xloc[14] = {34, 23, 1, 25, 28, 1, 23, 24, 1, 22, 24, 24, 24, 26};
  357.     char *vers[10] = {"Doom 1 v1.2",
  358.                           "Doom 1 v1.666",
  359.                           "Doom 2 v1.666",
  360.                           "Doom 2 v1.7",
  361.                           "Doom 2 v1.7a",
  362.                           "Doom v1.8",
  363.                           "Doom v1.9",
  364.                           "Linux X11 Doom v1.8",
  365.                           "Linux SVGA Doom v1.8",
  366.                           "User Defined"};
  367.     char *stats[4] = {"Version:",
  368.                             "EXE name:",
  369.                             "WAD name:",
  370.                             "Patch directory:"};
  371.     int i;
  372.  
  373.     image = new int[672];
  374.     image2 = new int[676];
  375.  
  376.     if (image == NULL || image2 == NULL)
  377.         AbortProg("in About");
  378.  
  379.     gettext(20, 12, 61, 30, image);
  380.     gettext(15, 33, 66, 41, image2);
  381.  
  382.     Drawframe(1, INFO, 20, 12, 60, 29);
  383.     Drawframe(1, INFO, 15, 33, 65, 40);
  384.     textattr(INFO);
  385.  
  386.     for (i=0; i<14; i++)
  387.         CPutsXY(xloc[i], i+14, about[i]);
  388.  
  389.     for (i=0; i<4; i++)
  390.         CPutsXY(18, i+35, stats[i]);
  391.  
  392.     CPutsXY(35, 35, vers[truever]);
  393.     CPutsXY(35, 36, doomexe);
  394.     CPutsXY(35, 37, doomwad);
  395.     CPutsXY(35, 38, patchdir);
  396.  
  397.     Waitforevent(YES);
  398.  
  399.     puttext(20, 12, 61, 30, image);
  400.     puttext(15, 33, 66, 41, image2);
  401.  
  402.     delete image;
  403.     delete image2;
  404. }
  405.  
  406. // Prints a text intro
  407.  
  408. void Printtextintro(void)
  409. {
  410.     puts("\nWelcome to DeHackEd v2.3\n");
  411.     puts("Written by Greg Lewis (\"Tree\"), gregl@umich.edu.");
  412.     puts("Vital Doom exe specs written by Matt Fell, msfell@aol.com.");
  413.     puts("Special thanks to iD for creating such a wonderful game!\n");
  414. }
  415.  
  416. // Prints command line options.
  417.  
  418. void Printoptions(void)
  419. {
  420.     puts("\n  Here is the proper command line syntax for DeHackEd:\n");
  421.     puts("\tdehacked [path] [-reload] [-load <patch1> ...] [-save <patch>]\n");
  422.     puts("  path             specify a different directory for doom(2).exe");
  423.     puts("  -reload          load original exe data into hacked exe");
  424.     puts("  -load patch(es)  load one or more patch files into the Doom exe file.");
  425.     puts("  -save patch      save the current Doom exe to a patch file");
  426. }
  427.  
  428. // Prints the sound screen
  429.  
  430. void Printsound(void)
  431. {
  432.     int i, current = global[SOUND_EDIT][TOPROW];
  433.     int start = 0, end = 38;
  434.     char buffer[7];
  435.  
  436.     if (redraw == DATA)
  437.     {
  438.         if (current == global[SOUND_EDIT][CUR])
  439.             end = 2;
  440.         else if (current + 37 == global[SOUND_EDIT][CUR])
  441.         {
  442.             start = 35;
  443.             current += 35;
  444.         }
  445.         else
  446.         {
  447.             start = (global[SOUND_EDIT][CUR] - current) - 1;
  448.             end = (global[SOUND_EDIT][CUR] - current) + 2;
  449.             current = global[SOUND_EDIT][CUR] - 1;
  450.         }
  451.     }
  452.  
  453.     textattr(NORMAL);
  454.  
  455.     if (redraw == ALL)
  456.     {
  457.         Drawframe(0, NORMAL, 16, 3, 64, 47);
  458.         CPutsXY(19, 5, "Sound            Text");
  459.         CPutsXY(19, 6, "Number  Name     Offset   0 / 1    \"Value\"");
  460.         CPutsXY(arrows[SOUND_EDIT][0], arrows[SOUND_EDIT][1], up_arrows[IBM_CHARSET]);
  461.         CPutsXY(arrows[SOUND_EDIT][2], arrows[SOUND_EDIT][3], down_arrows[IBM_CHARSET]);
  462.     }
  463.  
  464.     for (i=start; i<end; current++, i++)
  465.     {
  466.         Getsoundname(current+1, buffer);
  467.         Highlightname(buffer);
  468.         CPrintfXY(27, i+8, "%-6s", buffer);
  469.  
  470.         textattr(NORMAL);
  471.         CPrintfXY(19, i+8, "%4d", current+1);
  472.         CPrintfXY(36, i+8, "%5ld", sounddata[current][TEXTP] - toff[version]);
  473.         CPrintfXY(44, i+8, "%4ld", sounddata[current][ZERO_ONE]);
  474.         CPrintfXY(55, i+8, "%4ld", sounddata[current][VALUE]);
  475.     }
  476. }
  477.  
  478. // Prints the Sprite list
  479.  
  480. void Printsprite(void)
  481. {
  482.     int i, current = global[SPRITE_EDIT][TOPROW];
  483.     int start = 0, end = 38;
  484.     char buffer[5];
  485.  
  486.     if (redraw == DATA)
  487.     {
  488.         if (current == global[SPRITE_EDIT][CUR])
  489.             end = 2;
  490.         else if (current + 37 == global[SPRITE_EDIT][CUR])
  491.         {
  492.             start = 35;
  493.             current += 35;
  494.         }
  495.         else
  496.         {
  497.             start = (global[SPRITE_EDIT][CUR] - current) - 1;
  498.             end = (global[SPRITE_EDIT][CUR] - current) + 2;
  499.             current = global[SPRITE_EDIT][CUR] - 1;
  500.         }
  501.     }
  502.  
  503.     textattr(NORMAL);
  504.  
  505.     if (redraw == ALL)
  506.     {
  507.         Drawframe(0, NORMAL, 26, 3, 54, 47);
  508.         CPutsXY(29, 5, "Sprite   Text    Sprite");
  509.         CPutsXY(29, 6, "Number   Offset  Name");
  510.         CPutsXY(arrows[SPRITE_EDIT][0], arrows[SPRITE_EDIT][1], up_arrows[IBM_CHARSET]);
  511.         CPutsXY(arrows[SPRITE_EDIT][2], arrows[SPRITE_EDIT][3], down_arrows[IBM_CHARSET]);
  512.     }
  513.  
  514.     for (i=start; i<end; current++, i++)
  515.     {
  516.         textattr(NORMAL);
  517.         CPrintfXY(29, i+8, "%4d", current);
  518.         CPrintfXY(38, i+8, "%5ld", spritedata[current] - toff[version]);
  519.  
  520.         Getspritename(current, buffer);
  521.         Highlightname(buffer);
  522.         CPrintfXY(46, i+8, "%-4s", buffer);
  523.     }
  524. }
  525.  
  526. // Prints the text section of doom.exe
  527.  
  528. void Printtext(void)
  529. {
  530.     int i, j, current = global[TEXT_EDIT][TOPROW];
  531.     int start = 0, end = 38;
  532.     int convcur = 0;
  533.     int stringlen;
  534.     char buffer[64];
  535.  
  536.     for (i=0; i<global[TEXT_EDIT][CUR]; i++)
  537.     {
  538.         stringlen = strlen(&(textdatap[convcur]));
  539.         if ( Lnx_DOOM )
  540.             convcur += stringlen + 1;
  541.         else
  542.             convcur += (stringlen & (~3)) + 4;
  543.     }
  544.  
  545.     if (redraw == DATA)
  546.     {
  547.         if (current == global[TEXT_EDIT][CUR])
  548.             end = 2;
  549.         else if (current + 37 == global[TEXT_EDIT][CUR])
  550.         {
  551.             start = 35;
  552.             current += 35;
  553.         }
  554.         else
  555.         {
  556.             start = (global[TEXT_EDIT][CUR] - current) - 1;
  557.             end = (global[TEXT_EDIT][CUR] - current) + 2;
  558.             current = global[TEXT_EDIT][CUR] - 1;
  559.         }
  560.     }
  561.  
  562.     current = 0;
  563.  
  564.     for (i=0; i<global[TEXT_EDIT][TOPROW]+start; i++)
  565.     {
  566.         stringlen = strlen(&(textdatap[current]));
  567.         if ( Lnx_DOOM )
  568.             current += stringlen + 1;
  569.         else
  570.             current += (stringlen & (~3)) + 4;
  571.     }
  572.  
  573.     textattr(NORMAL);
  574.  
  575.     if (redraw == ALL)
  576.     {
  577.         Drawframe(0, NORMAL, 3, 3, 77, 47);
  578.         CPutsXY(5, 5, "Text");
  579.         CPutsXY(5, 6, "Offset   Text");
  580.         CPutsXY(arrows[TEXT_EDIT][0], arrows[TEXT_EDIT][1], up_arrows[IBM_CHARSET]);
  581.         CPutsXY(arrows[TEXT_EDIT][2], arrows[TEXT_EDIT][3], down_arrows[IBM_CHARSET]);
  582.     }
  583.  
  584.     for (i=start; i<end; i++)
  585.     {
  586.         CPrintfXY(5, i+8, "%6d", current);
  587.  
  588.         strncpy(buffer, &(textdatap[current]), 59);
  589.         if (strlen(&(textdatap[current])) > 58)
  590.         {
  591.             buffer[58] = 0;
  592.             strcat(buffer, "...");
  593.         }
  594.         for (j=0; j<strlen(buffer); j++)
  595.             if (buffer[j] == '\n' || buffer[j] == '\r' || buffer[j] == '\b' ||
  596.                  buffer[j] == '\f' || buffer[j] == '\t')
  597.                 buffer[j] = '~';
  598.         CPrintfXY(14, i+8, "%-62s", buffer);
  599.  
  600.         stringlen = strlen(&(textdatap[current]));
  601.         if ( Lnx_DOOM )
  602.             current += stringlen + 1;
  603.         else
  604.             current += (stringlen & (~3)) + 4;
  605.     }
  606. }
  607.  
  608. // Prints all of the Thing data in the correct places.
  609.  
  610. void Printthing(void)
  611. {
  612.     Printthingmisc();
  613.     Printthingsound();
  614.     Printthingframe();
  615.     Printthingbits();
  616.     Printthinginfo();
  617.     CPutsXY(arrows[THING_EDIT][0], arrows[THING_EDIT][1], up_arrows[IBM_CHARSET]);
  618.     CPutsXY(arrows[THING_EDIT][2], arrows[THING_EDIT][3], down_arrows[IBM_CHARSET]);
  619. }
  620.  
  621. void Printthingbits(void)
  622. {
  623.                           //12345678901234567890
  624.     char *data[32] = {"Gettable Thing",
  625.                             "Obstacle",
  626.                             "Shootable Thing",
  627.                             "Total Invisibility",
  628.                             "'Automatics'",
  629.                             "Semi-Deaf",
  630.                             "In Pain",
  631.                             "Unknown",
  632.                             "Hangs from Ceiling",
  633.                             "No Gravity",
  634.                             "Travels over Cliffs",
  635.                             "Can pick up items",
  636.                             "No Clipping",
  637.                             "Unknown",
  638.                             "Floating",
  639.                             "Semi-No Clipping",
  640.                             "Projectiles",
  641.                             "Disappearing Weapon",
  642.                             "Partial Invisibility",
  643.                             "Puffs (vs. bleeds)",
  644.                             "Sliding Helpless",
  645.                             "Unknown",
  646.                             "Counts for Kill %",
  647.                             "Counts for Item %",
  648.                             "Running",
  649.                             "Not in Deathmatch",
  650.                             "Color 1 (grey/red)",
  651.                             "Color 2 (brown/red)",
  652.                             "Unknown",
  653.                             "Unknown",
  654.                             "Unknown",
  655.                             "Unknown"};
  656.     char brackets[4] = "[ ]";
  657.     int i;
  658.  
  659.     if (redraw == ALL)
  660.         Drawframe(0, NORMAL, 10, 28, 70, 47);
  661.  
  662.     for (i=0; i<16; i++)
  663.     {
  664.         textattr(NORMAL);
  665.         switch (redraw)
  666.         {
  667.             case ALL:
  668.                 CPrintfXY(12, 30+i, "%2d", i);
  669.                 CPutsXY(19, 30+i, data[i]);
  670.             case ALLDATA:
  671.             case DATA:
  672.                 CPutsXY(15, 30+i, brackets);
  673.                 gotoxy(16, 30+i);
  674.                 if (thingdata[global[THING_EDIT][CUR]][BITS] & (1L << i))
  675.                     putch('X');
  676.             case NOT:
  677.                 break;
  678.         }
  679.     }
  680.  
  681.     for (i=16; i<32; i++)
  682.     {
  683.         switch (redraw)
  684.         {
  685.             case ALL:
  686.                 CPrintfXY(42, 14+i, "%2d", i);
  687.                 CPutsXY(49, 14+i, data[i]);
  688.             case ALLDATA:
  689.             case DATA:
  690.                 CPutsXY(45, 14+i, brackets);
  691.                 gotoxy(46, 14+i);
  692.                 if (thingdata[global[THING_EDIT][CUR]][BITS] & (1L << i))
  693.                     putch('X');
  694.             case NOT:
  695.                 break;
  696.         }
  697.     }
  698. }
  699.  
  700. // Prints out the frame part of the Thing editing screen
  701.  
  702. void Printthingframe(void)
  703. {
  704.     char temp[6];
  705.     int i = 25;
  706.     int end = 8;
  707.  
  708.     if (version == DOOM1_2)
  709.     {
  710.         i = 24;
  711.         end = 7;
  712.     }
  713.  
  714.     if (redraw == ALL)
  715.         Drawframe(0, NORMAL, 36, 14, 77, i);
  716.  
  717.     for (i=0; i<end; i++)
  718.     {
  719.         textattr(NORMAL);
  720.         switch (redraw)
  721.         {
  722.             case ALL:
  723.                 CPutsXY(38, i+16, thingfields[thingorder[i+15]]);
  724.                 CPutsXY(69, i+16, "[");
  725.                 CPutsXY(75, i+16, "]");
  726.             case ALLDATA:
  727.             case DATA:
  728.                 CPrintfXY(57, i+16, "%-11ld", thingdata[global[THING_EDIT][CUR]][thingorder[i+15]]);
  729.                 textattr(NORMAL);
  730.  
  731.                 Getframename((int)thingdata[global[THING_EDIT][CUR]][thingorder[i+15]], temp);
  732.                 Highlightname(temp);
  733.                 CPrintfXY(70, i+16, "%-5s", temp);
  734.             case NOT:
  735.                 break;
  736.         }
  737.     }
  738. }
  739.  
  740. // Prints out the little info part of the Thing editing screen
  741.  
  742. void Printthinginfo(void)
  743. {
  744.     char *info[2] = {"Thing Number:",
  745.                           "Thing Name:"};
  746.     int i;
  747.     char buffer[20];
  748.  
  749.     if (redraw == ALL)
  750.         Drawframe(0, NORMAL, 3, 3, 36, 8);
  751.     textattr(NORMAL);
  752.  
  753.     if (redraw == ALL)
  754.         for (i=0; i<2; i++)
  755.             CPutsXY(5, i+5, info[i]);
  756.  
  757.     CPrintfXY(19, 5, "%-5d", global[THING_EDIT][CUR]+1);
  758.  
  759.     Getthingname(global[THING_EDIT][CUR], buffer);
  760.     CPrintfXY(17, 6, "%-18s", buffer);
  761. }
  762.  
  763. // Prints all the Thing info, list style
  764.  
  765. void Printthinglist(void)
  766. {
  767.     int i, j, current = global[THING_LIST][TOPROW];
  768.     int start = 0, end = 38, tempspeed;
  769.     char buffer[20];
  770.     char xloc[4] = {32, 40, 52, 61};
  771.     char pformat[4][5] = {"%8ld", "%8ld", "%4d", "%4ld"};
  772.     char order[4] = {IDNUM, HP, SPEED, MISSILEDAMAGE};
  773.  
  774.     if (redraw == DATA)
  775.     {
  776.         if (current == global[THING_LIST][CUR])
  777.             end = 2;
  778.         else if (current + 37 == global[THING_LIST][CUR])
  779.         {
  780.             start = 35;
  781.             current += 35;
  782.         }
  783.         else
  784.         {
  785.             start = (global[THING_LIST][CUR] - current) - 1;
  786.             end = (global[THING_LIST][CUR] - current) + 2;
  787.             current = global[THING_LIST][CUR] - 1;
  788.         }
  789.     }
  790.  
  791.     textattr(NORMAL);
  792.  
  793.     if (redraw == ALL)
  794.     {
  795.         Drawframe(0, NORMAL, 4, 3, 76, 47);
  796.                         // 7890123456789012345678901234567890123456789012345678901234567890
  797.         CPutsXY(7, 5, "Thing                      Thing     Hit             Missile");
  798.         CPutsXY(7, 6, "Number  Name               ID #     Points   Speed   Damage");
  799.         CPutsXY(arrows[THING_LIST][0], arrows[THING_LIST][1], up_arrows[IBM_CHARSET]);
  800.         CPutsXY(arrows[THING_LIST][2], arrows[THING_LIST][3], down_arrows[IBM_CHARSET]);
  801.     }
  802.  
  803.     for (i=start; i<end; current++, i++)
  804.     {
  805.         textattr(NORMAL);
  806.         CPrintfXY(7, i+8, "%4d", current+1);
  807.  
  808.         Getthingname(current, buffer);
  809.         CPrintfXY(14, i+8, "%-19s", buffer);
  810.  
  811.         textattr(NORMAL);
  812.  
  813.         for (j=0; j<4; j++)
  814.         {
  815.             gotoxy(xloc[j], i+8);
  816.             if (j == 2)
  817.             {
  818.                 if ((current == 0) || !(thingdata[current][BITS] & 65536L))
  819.                     tempspeed = (int)thingdata[current][SPEED];
  820.                 else
  821.                     tempspeed = (int)(thingdata[current][SPEED] >> 16);
  822.                 cprintf(pformat[j], tempspeed);
  823.             }
  824.             else
  825.                 cprintf(pformat[j], thingdata[current][order[j]]);
  826.         }
  827.     }
  828.  
  829. }
  830.  
  831. // Prints out the miscellaneous part of the Thing editing screen
  832.  
  833. void Printthingmisc(void)
  834. {
  835.     int i;
  836.  
  837.     if (redraw == ALL)
  838.         Drawframe(0, NORMAL, 3, 12, 33, 25);
  839.  
  840.     for (i=0; i<10; i++)
  841.     {
  842.         textattr(NORMAL);
  843.         switch (redraw)
  844.         {
  845.             case ALL:
  846.                 CPutsXY(6, i+14, thingfields[thingorder[i]]);
  847.             case ALLDATA:
  848.             case DATA:
  849.                 gotoxy(21, i+14);
  850.                 if (thingorder[i] == CWIDTH || thingorder[i] == CHEIGHT ||
  851.                     ((thingorder[i] == SPEED) &&
  852.                     ((global[THING_EDIT][CUR] != 0) && 
  853.                     (thingdata[global[THING_EDIT][CUR]][BITS] & 1024L))))
  854.                     cprintf("%-11ld", thingdata[global[THING_EDIT][CUR]][thingorder[i]] >> 16);
  855.                 else
  856.                     cprintf("%-11ld", thingdata[global[THING_EDIT][CUR]][thingorder[i]]);
  857.             case NOT:
  858.                 break;
  859.         }
  860.     }
  861. }
  862.  
  863. // Prints out the sound portion of the Thing editing screen
  864.  
  865. void Printthingsound(void)
  866. {
  867.     char temp[7];
  868.     int i;
  869.  
  870.     if (redraw == ALL)
  871.         Drawframe(0, NORMAL, 39, 3, 77, 11);
  872.  
  873.     for (i=0; i<5; i++)
  874.     {
  875.         textattr(NORMAL);
  876.         switch (redraw)
  877.         {
  878.             case ALL:
  879.                 CPutsXY(41, i+5, thingfields[thingorder[i+10]]);
  880.                 CPutsXY(68, i+5, "[");
  881.                 CPutsXY(75, i+5, "]");
  882.             case ALLDATA:
  883.             case DATA:
  884.                 CPrintfXY(56, i+5, "%-11ld", thingdata[global[THING_EDIT][CUR]][thingorder[i+10]]);
  885.                 textattr(NORMAL);
  886.  
  887.                 Getsoundname((int)thingdata[global[THING_EDIT][CUR]][thingorder[i+10]], temp);
  888.                 Highlightname(temp);
  889.                 CPrintfXY(69, i+5, "%-6s", temp);
  890.             case NOT:
  891.                 break;
  892.         }
  893.     }
  894. }
  895.  
  896. // Prints a message, color is dependant on content.
  897.  
  898. EBool Printwindow(char *message, int type)
  899. {
  900.     int *image;
  901.     int x1, x2;
  902.     int c;
  903.     EBool escape = NO;
  904.  
  905.     if (batch == YES)
  906.     {
  907.         puts(message);
  908.         return NO;
  909.     }
  910.  
  911.     x1 = 40 - (4+strlen(message))/2;
  912.     x2 = 40 + (4+strlen(message))/2;
  913.  
  914.     // If x1 is < 1, x2 must be greater than 80.
  915.     if (x1 < 1)
  916.     {
  917.         x1 = 1;
  918.         x2 = 80;
  919.     }
  920.  
  921.     // Just get the whole screen (horiz) since we don't wanna bother
  922.     // figuring out how much exactly to do.
  923.     image = new int[480];
  924.  
  925.     if (image == NULL)
  926.         AbortProg("in Printwindow");
  927.  
  928.     gettext(1, 23, 80, 28, image);
  929.  
  930.     Drawframe(1, type, x1, 23, x2, 27);
  931.     textattr(type);
  932.  
  933.     CPutsXY(x1+2, 25, message);
  934.  
  935.     if (Waitforevent(NO)) {
  936.         if ( (c=getch()) == 0 )
  937.             getch();
  938.         else if ( c == ESC )
  939.             escape=YES;
  940.     }
  941.  
  942.     puttext(1, 23, 80, 28, image);
  943.  
  944.     delete image;
  945.  
  946.     return escape;
  947. }
  948.